package com.leha.mp.core.services.imp;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import com.github.pagehelper.PageHelper;
import com.leha.mp.core.Utils.Page;
import com.leha.mp.core.Utils.TimeIndexHelper;
import com.leha.mp.core.constants.BizConstants;
import com.leha.mp.core.constants.CoreErrorDict;
import com.leha.mp.core.dao.*;
import com.leha.mp.core.entity.mybatis.*;
import com.leha.mp.core.entity.vo.DoctorBaseInfoVo;
import com.leha.mp.core.entity.vo.UserLoginVO;
import com.leha.mp.core.entity.vo.VipDoctorInfo;
import com.leha.mp.core.services.AppUserService;
import com.leha.mp.core.services.BedgeServices;
import com.leha.mp.core.services.ErrorMessageServices;
import com.leha.mp.core.services.WAppServices;
import com.github.stuxuhai.jpinyin.PinyinException;
import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper;

import com.leha.utils.DateTool;
import me.chanjar.weixin.common.exception.WxErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
public class AppUserServiceImpl implements AppUserService {
    private static final Logger LOG = LoggerFactory.getLogger(AppUserServiceImpl.class);
    @Autowired
    PlUserMapper userMapper;
    @Autowired
    WAppServices appServices;
    @Autowired
    ErrorMessageServices errorMessageServices;
    @Autowired
    CustomLogicMapper customLogicMapper;
    @Autowired
    PlCaseMapper caseMapper;
    @Autowired
    PlOrderMapper orderMapper;
    @Autowired
    PlDockerUserRelationMapper relationMapper;
    @Autowired
    PlConsultingMapper consultingMapper;
    @Autowired
    PlDoctorCommentMapper commentMapper;
    @Autowired
    BedgeServices bedgeServices;

    @Override
    public UserLoginVO SaveInfo(Integer appId, Integer uid, String sessionKey, String encryptedData, String iv) {
        try {
            //PlUser user = userMapper.selectByPrimaryKey(uid);
            PlUser user  = new PlUser();
            user.setUid(uid);
            WxMaService wxService = appServices.getAppMAServices(appId);
            WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
            user.setAvatarUrl(userInfo.getAvatarUrl());
            user.setNickname(userInfo.getNickName());
            user.setChannel(appId);
            userMapper.updateByPrimaryKeySelective(user);
            return new UserLoginVO(user);
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            errorMessageServices.setError(CoreErrorDict.WXQRCodeRequsetFaild);
            return null;
        }
    }



    private List<DoctorBaseInfoVo> getDoctorInfo(String unionId, Integer uid) {
        List<DoctorBaseInfoVo> res = customLogicMapper.selectUserDoctor(unionId);
        /*PlConsultingExample ex = new PlConsultingExample();
        ex.createCriteria().andUserIdEqualTo(uid)
                .andStatusBetween(BizConstants.Consulting_Status_Payed, BizConstants.Consulting_Status_Accepted)
                .andConsultingTypeEqualTo(BizConstants.Consulting_Type_Msg);

        List<PlConsulting> consultings = consultingMapper.selectByExample(ex);
        for(DoctorBaseInfoVo df: res) {
            for(PlConsulting pc: consultings) {
                if(df.getId().equals(pc.getDoctorId())) {
                    if(df.getConsultings()==null) {
                        List<PlConsulting> c = new ArrayList<>();
                        c.add(pc);
                        df.setConsultings(c);
                    } else {
                        df.getConsultings().add(pc);
                    }
                }
            }
        }*/
        return res;
    }

    @Override
    public UserLoginVO Enter(Integer appId, String code) {
        WxMaService wxService = appServices.getAppMAServices(appId);
        if(wxService==null) {
            errorMessageServices.setError(CoreErrorDict.RESULT_ERROR);
            return null;
        }
        WxMaJscode2SessionResult session = null;
        try {
            session = wxService.getUserService().getSessionInfo(code);
        } catch (WxErrorException e) {
            e.printStackTrace();
            return null;
        }
        LOG.info(session.getSessionKey());
        LOG.info(session.getOpenid());
        PlUserExample ex = new PlUserExample();
        ex.createCriteria().andOpenidEqualTo(session.getOpenid());
        List<PlUser> user = userMapper.selectByExample(ex);
        if(user.size()==0) {
            PlUser newUser = new PlUser();
            newUser.setOpenid(session.getOpenid());
            newUser.setChannel(appId);
            newUser.setUnionid(session.getUnionid());
            LOG.info("unionId:", session.getUnionid());
            userMapper.insertSelective(newUser);
            UserLoginVO vo = new UserLoginVO(newUser, session.getSessionKey());
            vo.setDoctorBaseInfo(getDoctorInfo(newUser.getUnionid(), newUser.getUid()));
            return vo;
        } else {
            PlUser u = user.get(0);
            if(u.getUnionid()==null || u.getUnionid().isEmpty()) {
                u.setUnionid(session.getUnionid());
                userMapper.updateByPrimaryKeySelective(u);
            }
            UserLoginVO vo = new UserLoginVO(u, session.getSessionKey());
            vo.setLastConsultingId(customLogicMapper.getLastConsulting(u.getUid(), TimeIndexHelper.getCurrentTimeIndex()));
            vo.setDoctorBaseInfo(getDoctorInfo(u.getUnionid(), u.getUid()));

            // @add yanming 查找即将开始的咨询记录，按时间排序取第一个
            vo.setLatestConsultingVo(customLogicMapper.getUserLatestConsulting(u.getUid()));
            
            return vo;
        }
    }

    @Override
    public List<DoctorBaseInfoVo> getMyDoctor(Integer uid) {
        PlUser u = userMapper.selectByPrimaryKey(uid);
        return getDoctorInfo(u.getUnionid(), uid);
    }

    @Override
    public Boolean SavePhone(Integer uid, String phone) {
        PlUser u = new PlUser();
        u.setUid(uid);
        u.setPhone(phone);
        return userMapper.updateByPrimaryKeySelective(u) > 0;
    }

    @Override
    public Boolean saveCase(PlCase ucase) {
        PlCaseExample ex = new PlCaseExample();
        ex.createCriteria().andUidEqualTo(ucase.getUid()).andDoctorIdEqualTo(ucase.getDoctorId());
        List<PlCase> cases = caseMapper.selectByExample(ex);
        if(cases.size()>0) {
            errorMessageServices.setError(CoreErrorDict.CaseExist);
            return false;
        }

        try {
            ucase.setShortPinyin(PinyinHelper.getShortPinyin(ucase.getName()));
            ucase.setFullPinyin(PinyinHelper.convertToPinyinString(ucase.getName(), ",", PinyinFormat.WITHOUT_TONE));
            ucase.setStatus(BizConstants.CaseStats_Reviewing);
        } catch (PinyinException e) {
            e.printStackTrace();
        }
        boolean ret = caseMapper.insertSelective(ucase)>0;
        if(ret) {
            PlUser u = userMapper.selectByPrimaryKey(ucase.getUid());
            u.setName(ucase.getName());
            u.setSex(ucase.getSex());
            u.setAge(ucase.getAge());
            u.setAddress(ucase.getLocation());
            userMapper.updateByPrimaryKeySelective(u);
            PlDockerUserRelation re = new PlDockerUserRelation();
            re.setDockerId(ucase.getDoctorId());
            re.setUnionid(u.getUnionid());
            re.setStatus(BizConstants.CaseStats_Reviewing);
            relationMapper.updateByPrimaryKeySelective(re);
            bedgeServices.UpdateDoctorBedge(ucase.getDoctorId(), BedgeServices.Type_Doctor_My_Patients, u.getUid(), 1);
        }
        return ret;
    }

    @Override
    public String getOpenId(Integer userId) {
        PlUser u = userMapper.selectByPrimaryKey(userId);
        return u.getOpenid();
    }

    @Override
    public List<PlOrder> getUserOrders(Integer userId, Integer type, Page page) {
        PlOrderExample ex = new PlOrderExample();
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        if(type==-1) {
            ex.createCriteria().andUidEqualTo(userId);
        } else {
            ex.createCriteria().andUidEqualTo(userId).andOrderStatusEqualTo(type.byteValue());
        }
        return orderMapper.selectByExample(ex);
    }

    @Override
    public PlDoctorComment getMyEvaluate(Integer consutingId, Integer userId) {
        return commentMapper.selectByPrimaryKey(consutingId);
    }

    @Override
    public List<VipDoctorInfo> getMyVipDoctor(Integer userId) {
        List<VipDoctorInfo> res = customLogicMapper.getVipUserDoctor(userId);
        return res;
    }

    @Override
    public UserLoginVO GetUserInfo(Integer userId) {
        PlUser u = userMapper.selectByPrimaryKey(userId);
        UserLoginVO vo = new UserLoginVO(u);
        vo.setLastConsultingId(customLogicMapper.getLastConsulting(u.getUid(), TimeIndexHelper.getCurrentTimeIndex()));
        vo.setDoctorBaseInfo(getDoctorInfo(u.getUnionid(), u.getUid()));
        // @add yanming 查找即将开始的咨询记录，按时间排序取第一个
        vo.setLatestConsultingVo(customLogicMapper.getUserLatestConsulting(u.getUid()));
        return vo;
    }
}
